home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * $Id: k3bdevice.h 679274 2007-06-23 13:23:58Z trueg $
- * Copyright (C) 2003-2007 Sebastian Trueg <trueg@k3b.org>
- *
- * This file is part of the K3b project.
- * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * See the file "COPYING" for the exact licensing terms.
- */
-
-
- #ifndef K3BDEVICE_H
- #define K3BDEVICE_H
-
- #include <qstringlist.h>
- #include <qvaluelist.h>
- #include <qglobal.h>
-
- #include <k3bdevicetypes.h>
- #include <k3bdiskinfo.h>
- #include <k3bcdtext.h>
- #include <k3bmsf.h>
- #include <k3bdevice_export.h>
-
- #ifdef Q_OS_FREEBSD
- struct cam_device;
- #endif
-
- namespace K3bDevice
- {
- class Toc;
-
- /**
- * \brief The main class representing a device.
- *
- * Devices are constructed by the DeviceManager.
- *
- * All methods except for open and close in Device are thread-safe which basicly means that
- * no two commands are sent to the device at the same time.
- */
- // FIXME: all methods are const which makes no sense at all!
- class LIBK3BDEVICE_EXPORT Device
- {
- public:
- #ifdef Q_OS_FREEBSD
- typedef struct cam_device* Handle;
- #else
- // file descriptor
- typedef int Handle;
- #endif
-
- /**
- * The available cdrdao drivers
- * \deprecated This will be moved to libk3b
- */
- static const char* cdrdao_drivers[];
-
- // FIXME: make this protected
- ~Device();
-
- /**
- * The interface type.
- *
- * \return K3bDevice::SCSI or K3bDevice::IDE.
- */
- Interface interfaceType() const;
-
- /**
- * \deprecated use readCapabilities() and writeCapabilities()
- * The device type.
- *
- * @return A bitwise or of K3bDevice::DeviceType.
- */
- int type() const;
-
- /**
- * The mediatypes this device is able to read.
- *
- * \return A bitwise or of K3bDevice::MediaType
- */
- int readCapabilities() const;
-
- /**
- * The media types this device is able to write.
- *
- * \return A bitwise or of K3bDevice::MediaType
- */
- int writeCapabilities() const;
-
- /**
- * \return Vendor string as reported by the device's firmware.
- */
- const QString& vendor() const { return m_vendor; }
-
- /**
- * \return Description string as reported by the device's firmware.
- */
- const QString& description() const { return m_description; }
-
- /**
- * \return Version string as reported by the device's firmware.
- */
- const QString& version() const { return m_version; }
-
- /**
- * Shortcut for \code writesCd() || writesDvd() \endcode
- *
- * \return true if the device is able to burn media.
- */
- bool burner() const;
-
- /**
- * Shortcut for \code type() & DEVICE_CD_R \endcode
- *
- * \return true if the device is able to burn CD-R media.
- */
- bool writesCd() const;
-
- /**
- * Shortcut for \code type() & DEVICE_CD_RW \endcode
- *
- * \return true if the device is able to burn CD-RW media.
- */
- bool writesCdrw() const;
-
- /**
- * Shortcut for \code writesDvdMinus() || writesDvdPlus() \endcode
- *
- * \return true if the device is able to burn DVD media.
- */
- bool writesDvd() const;
-
-
- /**
- * Shortcut for \code type() & (DEVICE_DVD_PLUS_R|DEVICE_DVD_PLUS_RW) \endcode
- *
- * \return true if the device is able to burn DVD+R or DVD+RW media.
- */
- bool writesDvdPlus() const;
-
- /**
- * Shortcut for \code type() & (DEVICE_DVD_R|DEVICE_DVD_RW) \endcode
- *
- * \return true if the device is able to burn DVD-R or DVD-RW media.
- */
- bool writesDvdMinus() const;
-
- /**
- * Shortcut for \code type() & DEVICE_DVD_ROM \endcode
- *
- * \return true if the device is able to read DVD media.
- */
- bool readsDvd() const;
-
- /**
- * @deprecated Use burnfree()
- */
- bool burnproof() const;
-
- /**
- * @return true is the device is a writer and supports buffer underrun free recording (BURNFREE)
- */
- bool burnfree() const;
-
- /**
- * Shortcut for \code writingModes() & WRITINGMODE_SAO \endcode
- *
- * \deprecated use supportsWritingMode()
- */
- bool dao() const;
-
- /**
- * Check if the device supports a certain writing mode.
- *
- * \return true if the device supports the requested writing mode or false otherwise.
- */
- bool supportsWritingMode( WritingMode mode ) const { return (m_writeModes & mode); }
-
- /**
- * Shortcut for
- * \code
- * writingModes() & (WRITINGMODE_RAW|WRITINGMODE_RAW_R16|WRITINGMODE_RAW_R96P|WRITINGMODE_RAW_R96R)
- * \endcode
- */
- bool supportsRawWriting() const;
-
- /**
- * @return true if the device is a DVD-R(W) writer which supports test writing.
- */
- bool dvdMinusTestwrite() const { return m_dvdMinusTestwrite; }
-
- int maxReadSpeed() const { return m_maxReadSpeed; }
- int currentWriteSpeed() const { return m_currentWriteSpeed; }
-
- /**
- * Size of the device's internal writing buffer.
- *
- * \return The size of the buffer in KB.
- */
- int bufferSize() const { return m_bufferSize; }
-
- /**
- * @return the corresponding device name.
- */
- const QString& devicename() const;
-
- /**
- * for SCSI devices this should be something like /dev/scd0 or /dev/sr0
- * for IDE device this should be something like /dev/hdb1
- */
- const QString& blockDeviceName() const { return m_blockDevice; }
-
- /**
- * This is only valid for SCSI devices. Without devfs it's something
- * like /dev/sg0. Otherwise something like /dev/scsi/host0/bus0/target0/lun0/generic.
- *
- * This is not needed in K3b at all. But cdrecord and cdrdao use the sg devices and
- * we need it to fixup it's permissions in K3bSetup.
- */
- const QString& genericDevice() const { return m_genericDevice; }
-
- /**
- * \return All device nodes for this drive.
- */
- const QStringList& deviceNodes() const;
-
- /**
- * \see K3bDevice::Device::deviceNodes()
- */
- void addDeviceNode( const QString& );
-
- /**
- * Makes only sense to use with scsi devices
- * @return a string for use with the cdrtools
- * @deprecated
- */
- QString busTargetLun() const;
-
- int scsiBus() const { return m_bus; }
- int scsiId() const { return m_target; }
- int scsiLun() const { return m_lun; }
-
- int maxWriteSpeed() const { return m_maxWriteSpeed; }
-
- /**
- * \deprecated the cdrdao driver has no place in this library. It will be removed.
- */
- const QString& cdrdaoDriver() const { return m_cdrdaoDriver; }
-
- /**
- * returns: 0 auto (no cdrdao-driver selected)
- * 1 yes
- * 2 no
- *
- * \deprecated cdrdao specific stuff has no place in this library. It will be removed.
- */
- int cdTextCapable() const;
-
- /**
- * internal K3b value.
- * \deprecated This should not be handled here.
- */
- void setCurrentWriteSpeed( int s ) { m_currentWriteSpeed = s; }
-
- /**
- * Use this if the speed was not detected correctly.
- */
- void setMaxReadSpeed( int s ) { m_maxReadSpeed = s; }
-
- /**
- * Use this if the speed was not detected correctly.
- */
- void setMaxWriteSpeed( int s ) { m_maxWriteSpeed = s; }
-
- /**
- * Use this if cdrdao is not able to autodetect the nessessary driver.
- * \deprecated the cdrdao driver has no place in this library. It will be removed.
- */
- void setCdrdaoDriver( const QString& d ) { m_cdrdaoDriver = d; }
-
- /**
- * Only used if the cdrdao-driver is NOT set to "auto".
- * In that case it must be manually set because there
- * is no way to autosense the cd-text capability.
- *
- * \deprecated the cdrdao driver has no place in this library. It will be removed.
- */
- void setCdTextCapability( bool );
-
- /**
- * checks if unit is ready (medium inserted and ready for command)
- *
- * Refers to the MMC command: TEST UNIT READY
- */
- bool testUnitReady() const;
-
- /**
- * checks if disk is empty, returns @p K3bDevice::State
- */
- int isEmpty() const;
-
- /**
- * @return true if inserted media is rewritable.
- */
- bool rewritable() const;
-
- /**
- * Check if the inserted media is a DVD.
- *
- * \return true if the inserted media is a DVD.
- */
- bool isDVD() const;
-
- /**
- * @return The number of sessions on the media.
- */
- int numSessions() const;
-
- /**
- * @return The toc of the media or an empty (invalid) K3bDevice::Toc if
- * no or an empty media is inserted.
- */
- Toc readToc() const;
-
- /**
- * Append ISRC and MCN to the TOC if found
- * This has been moved to a separate method since it can take a very long time
- * to scan for all ISRCs.
- */
- void readIsrcMcn( Toc& toc ) const;
-
- /**
- * Read the CD-TEXT of an audio or mixed-mode CD.
- *
- * \return A CdText object filled with the CD-TEXT values or an empty one in case of
- * pure data media or if the CD does not contain CD-TEXT.
- */
- CdText readCdText() const;
-
- /**
- * @return The K3bDevice::Track::DataMode of the track.
- * @see K3bDevice::Track
- */
- int getTrackDataMode( const Track& track ) const;
-
- /**
- * @return the mode of a data track. K3bDevice::Track::MODE1, K3bDevice::Track::MODE2,
- * K3bDevice::Track::XA_FORM1, or K3bDevice::Track::XA_FORM2.
- */
- int getDataMode( const K3b::Msf& sector ) const;
-
- /**
- * block or unblock the drive's tray
- * \return true on success and false on error.
- * \see eject()
- */
- bool block( bool ) const;
-
- /**
- * Eject the media.
- * \return true on success and false on error.
- * \see load()
- */
- bool eject() const;
-
- /**
- * Load the media.
- * @return true on success and false on error.
- */
- bool load() const;
-
- /**
- * Enable or disable auto-ejecting. For now this is a no-op on non-Linux systems.
- * \param enabled if true auto-ejecting will be enabled, otherwise disabled.
- * \return true if the operation was successful, false otherwise
- */
- bool setAutoEjectEnabled( bool enabled ) const;
-
- /**
- * The supported writing modes.
- *
- * \return A bitwise or of K3bDevice::WritingMode or 0 in case of a read-only device.
- */
- int writingModes() const { return m_writeModes; }
-
- bool readSectorsRaw(unsigned char *buf, int start, int count) const;
-
- /**
- * Get a list of supported profiles. See enumeration MediaType.
- */
- int supportedProfiles() const;
-
- /**
- * Tries to get the current profile from the drive.
- * @returns -1 on error (command failed or unknown profile)
- * MediaType otherwise (MEDIA_NONE means: no current profile)
- */
- int currentProfile() const;
-
- /**
- * Check if a certain feature is current.
- * \see k3bdevicetypes.h for feature constants.
- * \return 1 if the feature is current, 0 if not, -1 on error
- */
- int featureCurrent( unsigned int feature ) const;
-
- /**
- * This is the method to use!
- */
- DiskInfo diskInfo() const;
-
- /**
- * Refers to MMC command READ CAPACITY
- */
- bool readCapacity( K3b::Msf& ) const;
-
- /**
- * Refers to MMC command READ FORMAT CAPACITY
- *
- * @param wantedFormat The requested format type.
- * @param result If true is returned this contains the requested value.
- * @param currentMax If not 0 this will be filled with the Current/Maximum Descriptor value.
- * @param currentMax If not 0 this will be filled with the Current/Maximum Format Type.
- */
- bool readFormatCapacity( int wantedFormat, K3b::Msf& result,
- K3b::Msf* currentMax = 0, int* currentMaxFormat = 0 ) const;
-
- /**
- * Determine the type of the currently mounted medium
- *
- * @returns K3bDevice::MediaType
- */
- int mediaType() const;
-
- /**
- * Returnes the list of supported writing speeds as reported by
- * mode page 2Ah.
- *
- * This only works with MMC3 compliant drives.
- */
- QValueList<int> determineSupportedWriteSpeeds() const;
-
- /**
- * @returnes the speed in kb/s or 0 on failure.
- */
- int determineMaximalWriteSpeed() const;
-
- /**
- * Open the device for access via a file descriptor.
- * @return true on success or if the device is already open.
- * @see close()
- *
- * Be aware that this method is not thread-safe.
- */
- bool open( bool write = false ) const;
-
- /**
- * Close the files descriptor.
- * @see open()
- *
- * Be aware that this method is not thread-safe.
- */
- void close() const;
-
- /**
- * @return true if the device was successfully opened via @p open()
- */
- bool isOpen() const;
-
- /**
- * fd on linux, cam on bsd
- */
- Handle handle() const;
-
- /**
- * \return \li -1 on error (no DVD)
- * \li 1 (CSS/CPPM)
- * \li 2 (CPRM) if scrambled
- * \li 0 otherwise
- */
- int copyrightProtectionSystemType() const;
-
- // MMC commands
-
- /**
- * SET SPEED command
- *
- * @param readingSpeed The preferred reading speed (0x0000-0xFFFE). 0xFFFF requests
- * fot the logical unit to select the optimal speed.
- * @param writingSpeed The preferred writing speed (0x0000-0xFFFE). 0xFFFF requests
- * fot the logical unit to select the optimal speed.
- * @param cav Is the speed pure CAV?
- */
- bool setSpeed( unsigned int readingSpeed,
- unsigned int writingSpeed,
- bool cav = false ) const;
-
- /**
- * if true is returned dataLen specifies the actual length of *data which needs to be
- * deleted after using.
- */
- bool readDiscInformation( unsigned char** data, unsigned int& dataLen ) const;
-
- /**
- * @param pf If false all fields in the descriptor data is vendor specific. Default should be true.
- */
- bool modeSelect( unsigned char* page, unsigned int pageLen, bool pf, bool sp ) const;
-
- /**
- * if true is returned pageLen specifies the actual length of *pageData which needs to be
- * deleted after using.
- */
- bool modeSense( unsigned char** pageData, unsigned int& pageLen, int page ) const;
-
- /**
- * if true is returned dataLen specifies the actual length of *data which needs to be
- * deleted after using.
- */
- bool readTocPmaAtip( unsigned char** data, unsigned int& dataLen, int format, bool msf, int track ) const;
-
- /**
- * @param type specifies what value means:
- * \li 00b - value refers to a logical block address
- * \li 01b - value refers to a track number where 0 will treat the lead-in as if it
- * were a logical track and ffh will read the invisible or incomplete track.
- * \li 10b - value refers to a session number
- *
- */
- bool readTrackInformation( unsigned char** data, unsigned int& dataLen, int type, int value ) const;
-
- /**
- * if true is returned dataLen specifies the actual length of *data which needs to be
- * deleted after using.
- */
- bool readDiscStructure( unsigned char** data, unsigned int& dataLen,
- unsigned int mediaType = 0x0,
- unsigned int format = 0x0,
- unsigned int layer = 0x0,
- unsigned long adress = 0,
- unsigned int agid = 0x0 ) const;
-
- /**
- * In MMC5 readDvdStructure was renamed to readDiscStructure. This method does the same
- * like the above.
- */
- bool readDvdStructure( unsigned char** data, unsigned int& dataLen,
- unsigned int format = 0x0,
- unsigned int layer = 0x0,
- unsigned long adress = 0,
- unsigned int agid = 0x0 ) const;
-
- /**
- * if true is returned dataLen specifies the actual length of *data which needs to be
- * deleted after using.
- */
- bool mechanismStatus( unsigned char** data, unsigned int& dataLen ) const;
-
- /**
- * Read a single feature.
- * data will be filled with the feature header and the descriptor
- */
- bool getFeature( unsigned char** data, unsigned int& dataLen, unsigned int feature ) const;
-
-
- /**
- * if true is returned dataLen specifies the actual length of *data which needs to be
- * deleted after using.
- */
- bool getPerformance( unsigned char** data, unsigned int& dataLen,
- unsigned int type,
- unsigned int dataType,
- unsigned int lba = 0 ) const;
-
- /**
- * @param sectorType: \li 000b - all types
- * \li 001b - CD-DA
- * \li 010b - Mode 1
- * \li 011b - Mode 2 formless
- * \li 100b - Mode 2 form 1
- * \li 101b - Mode 2 form 2
- *
- * @param startAdress Lba 0 is mapped to msf 00:00:00 so this method uses
- * startAdress+150 as the starting msf.
- *
- * @param endAdress This is the ending address which is NOT included in the read operation.
- * Lba 0 is mapped to msf 00:00:00 so this method uses
- * endAdress+150 as the ending msf.
- *
- * @param c2: \li 00b - No error info
- * \li 01b - 294 bytes, one bit for every byte of the 2352 bytes
- * \li 10b - 296 bytes, xor of all c2 bits, zero pad bit, 294 c2 bits
- *
- * @param subChannel: \li 000b - No Sub-channel data
- * \li 001b - RAW P-W Sub-channel (96 bytes)
- * \li 010b - Formatted Q Sub-channel (16 bytes)
- * \li 100b - Corrected and de-interleaved R-W Sub-channel (96 bytes)
- */
- bool readCdMsf( unsigned char* data,
- unsigned int dataLen,
- int sectorType,
- bool dap,
- const K3b::Msf& startAdress,
- const K3b::Msf& endAdress,
- bool sync,
- bool header,
- bool subHeader,
- bool userData,
- bool edcEcc,
- int c2,
- int subChannel ) const;
-
- /**
- * @param sectorType: \li 000b - all types
- * \li 001b - CD-DA
- * \li 010b - Mode 1
- * \li 011b - Mode 2 formless
- * \li 100b - Mode 2 form 1
- * \li 101b - Mode 2 form 2
- *
- * @param c2: \li 00b - No error info
- * \li 01b - 294 bytes, one bit for every byte of the 2352 bytes
- * \li 10b - 296 bytes, xor of all c2 bits, zero pad bit, 294 c2 bits
- *
- * @param subChannel: \li 000b - No Sub-channel data
- * \li 001b - RAW P-W Sub-channel (96 bytes)
- * \li 010b - Formatted Q Sub-channel (16 bytes)
- * \li 100b - Corrected and de-interleaved R-W Sub-channel (96 bytes)
- */
- bool readCd( unsigned char* data,
- unsigned int dataLen,
- int sectorType,
- bool dap,
- unsigned long startAdress,
- unsigned long length,
- bool sync,
- bool header,
- bool subHeader,
- bool userData,
- bool edcEcc,
- int c2,
- int subChannel ) const;
-
- bool read10( unsigned char* data,
- unsigned int dataLen,
- unsigned long startAdress,
- unsigned int length,
- bool fua = false ) const;
-
- bool read12( unsigned char* data,
- unsigned int dataLen,
- unsigned long startAdress,
- unsigned long length,
- bool streaming = false,
- bool fua = false ) const;
-
- /**
- * @param subchannelParam: 01h - CD current position
- * 02h - Media Catalog number (UPC/bar code)
- * 03h - ISRC
- * @param trackNumber only valid if subchannelParam == 03h
- */
- bool readSubChannel( unsigned char** data,
- unsigned int& dataLen,
- unsigned int subchannelParam,
- unsigned int trackNumber ) const;
-
- bool readIsrc( unsigned int track, QCString& isrc ) const;
-
- bool readMcn( QCString& mcn ) const;
-
- /**
- * MMC command Read Buffer Capacity
- *
- * \return \see K3bScsiCommand::transport()
- */
- int readBufferCapacity( long long& bufferLength, long long& bufferAvail ) const;
-
- /**
- * @returns the index number on success
- * -1 on general error
- * and -2 if there is no index info in that frame
- */
- int getIndex( unsigned long lba ) const;
-
- bool searchIndex0( unsigned long startSec, unsigned long endSec, long& pregapStart ) const;
-
- /**
- * For now this just searches index 0 for all tracks and sets
- * the value in the tracks.
- * In the future this should scan for all indices.
- */
- bool indexScan( K3bDevice::Toc& toc ) const;
-
- /**
- * Seek to the specified sector.
- */
- bool seek( unsigned long lba ) const;
-
- bool getNextWritableAdress( unsigned int& lastSessionStart, unsigned int& nextWritableAdress ) const;
-
- /**
- * Retrieve the next writable address from the currently mounted writable medium.
- * \return The next writable address if the medium is empty or appendable or -1
- * if an error occured.
- */
- int nextWritableAddress() const;
-
- /**
- * Locks the device for usage. This means that no MMC command can be performed
- * until usageUnlock is called.
- *
- * Locking a device is useful when an external application or library is called
- * that opens the device itself.
- *
- * \sa usageUnlock
- */
- void usageLock() const;
-
- /**
- * Unlock the device after a call to usageLock.
- */
- void usageUnlock() const;
-
- /**
- * Thread-safe ioctl call for this device for Linux and Net-BSD systems.
- * Be aware that so far this does not include opening the device
- */
- // int ioctl( int request, ... ) const;
-
- protected:
- bool furtherInit();
-
- #ifdef Q_OS_LINUX
- /**
- * Fallback method that uses the evil cdrom.h stuff
- */
- bool readTocLinux( Toc& ) const;
- #endif
-
- /**
- * The preferred toc reading method for all CDs. Also reads session info.
- * undefined for DVDs.
- */
- bool readRawToc( Toc& ) const;
- bool readFormattedToc( Toc&, int mediaType ) const;
-
- /**
- * Fixes the last block on CD-Extra disks. This is needed if the readRawToc failed since
- * in that case the first sector of the last session's first track is used as the previous
- * session's last track's last sector which is wrong. There is a 11400 block session lead-in
- * between them. This method fixes this only for the last session and only on linux.
- */
- bool fixupToc( Toc& ) const;
-
- private:
- /**
- * A Device can only be constructed the the DeviceManager.
- */
- Device( const QString& devname );
-
- /**
- * Determines the device's capabilities. This needs to be called once before
- * using the device.
- *
- * Should only be used by the DeviceManager.
- *
- * @param checkWritingModes if true the CD writing modes will be checked using
- * MMC_MODE_SELECT.
- */
- bool init( bool checkWritingModes = true );
-
- void searchIndexTransitions( long start, long end, K3bDevice::Track& track ) const;
- void checkWritingModes();
- void checkFeatures();
- void checkForJustLink();
- void checkFor2AFeatures();
- void checkForAncientWriters();
-
- /**
- * Internal method which checks if the raw toc data has bcd values or hex.
- * @return 0 if hex, 1 if bcd, -1 if none
- */
- int rawTocDataWithBcdValues( unsigned char* data, unsigned int dataLen ) const;
-
- bool getSupportedWriteSpeedsVia2A( QValueList<int>& list, bool dvd ) const;
- bool getSupportedWriteSpeedsViaGP( QValueList<int>& list, bool dvd ) const;
-
- QCString mediaId( int mediaType ) const;
-
- QString m_vendor;
- QString m_description;
- QString m_version;
- QString m_cdrdaoDriver;
- int m_cdTextCapable;
- int m_maxReadSpeed;
- int m_maxWriteSpeed;
- int m_currentWriteSpeed;
-
- bool m_dvdMinusTestwrite;
-
- // only needed for scsi devices
- int m_bus;
- int m_target;
- int m_lun;
-
- int m_bufferSize;
-
- int m_writeModes;
-
- // only needed on FreeBSD
- QString m_passDevice;
- QString m_blockDevice;
- QString m_genericDevice;
-
- class Private;
- Private* d;
- friend class DeviceManager;
- };
-
- #if defined(Q_OS_LINUX) || defined(Q_OS_NETBSD)
- /**
- * This should always be used to open a device since it
- * uses the resmgr
- *
- * @internal
- */
- int openDevice( const char* name, bool write = false );
- #endif
- }
-
- #endif
-